home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / mouse.exe / MOUSESUB.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-06-03  |  14.8 KB  |  378 lines

  1.  
  2. { This is the MOUSESUB.PAS include file for the MOUSE.PAS unit. }
  3. { It contains various special mouse routines used by the Mouse unit. }
  4.  
  5. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  6. {Special inline functions used by the Mouse unit}
  7.  
  8. {---------------------------------------------------------------------------}
  9. { an inline function to limit an integer between min and max values}
  10. function IntLimit(Val,Min,Max:Integer):Integer;
  11. Inline(
  12.    $58        {  pop AX}
  13.   /$5B        {  pop BX}
  14.   /$59        {  pop CX}
  15.   /$39/$C8    {  cmp AX,CX}
  16.   /$7C/$08    {  jl done}
  17.   /$89/$D8    {  mov AX,BX}
  18.   /$39/$C8    {  cmp AX,CX}
  19.   /$7F/$02    {  jg done}
  20.   /$89/$C8);  {  mov AX,CX}
  21.               {done:}
  22.  
  23.  
  24. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  25. { The following procedures use the mouse functions to provide }
  26. { a higher level of control over the mouse }
  27.  
  28. {---------------------------------------------------------------------------}
  29. { Normalizes a mouse X position to standard position info }
  30.  
  31. function GetMx(X:Integer):Integer;
  32. begin
  33.    case CrtMode of
  34.      0,1 : begin
  35.              if MaxCrtX < 64 then
  36.                 MouseTemp := (X shr 1) div MouseTextWidth      {320x200 text}
  37.              else
  38.                 MouseTemp := X div MouseTextWidth;             {???x??? text}
  39.            end;
  40.      2,3 : MouseTemp := X div MouseTextWidth;                  {640x200 text}
  41.      4,5 : begin
  42.              if HercGraphMouse then
  43.                MouseTemp := X                         {720x348 herc graphics}
  44.              else
  45.                MouseTemp := X shr 1;                       {320x200 graphics}
  46.            end;
  47.      6   : MouseTemp := X;                                 {640x200 graphics}
  48.      7   : MouseTemp := X div MouseTextWidth;                  {640x??? text}
  49.      $D,$13 : MouseTemp := X shr 1;                        {320x200 graphics}
  50.    else
  51.      MouseTemp := X;                                       {640x??? graphics}
  52.    end;
  53.  
  54.    if ZeroMouse then
  55.      GetMx := MouseTemp                        {zero based mouse positioning}
  56.    else
  57.      GetMx := succ(MouseTemp);            {mouse positioning starts with one}
  58. end;
  59.  
  60. {---------------------------------------------------------------------------}
  61. { Normalizes a mouse Y position to standard position info }
  62.  
  63. function GetMy(Y:Integer):Integer;
  64. begin
  65.    if TextMouse then
  66.      MouseTemp := Y div MouseTextHeight     {convert position for text modes}
  67.    else
  68.      MouseTemp := Y;                      {no conversion needed for graphics}
  69.  
  70.    if ZeroMouse then
  71.      GetMy := MouseTemp                        {zero based mouse positioning}
  72.    else
  73.      GetMy := succ(MouseTemp);            {mouse positioning starts with one}
  74. end;
  75.  
  76. {---------------------------------------------------------------------------}
  77. { converts a standard X position to a mouse X position }
  78.  
  79. function PutMx(X:Integer):Integer;
  80. begin
  81.    if ZeroMouse then
  82.      MouseTemp := X                            {zero based mouse positioning}
  83.    else
  84.      MouseTemp := pred(X);                {mouse positioning starts with one}
  85.  
  86.    if MouseTemp < 0 then                                 {clip value to zero}
  87.      MouseTemp := 0;
  88.  
  89.    case CrtMode of
  90.      0,1 : begin
  91.              if MaxCrtX < 64 then
  92.                PutMx := (MouseTemp * MouseTextWidth) shl 1     {320x200 text}
  93.              else
  94.                PutMx := MouseTemp * MouseTextWidth;            {???x??? text}
  95.            end;
  96.      2,3 : PutMx := MouseTemp * MouseTextWidth;                {640x200 text}
  97.      4,5 : begin
  98.              if HercGraphMouse then
  99.                PutMx := MouseTemp                     {720x348 herc graphics}
  100.              else
  101.                PutMx := MouseTemp shl 1;                   {320x200 graphics}
  102.            end;
  103.      6   : PutMx := MouseTemp;                             {640x200 graphics}
  104.      7   : PutMx := MouseTemp * MouseTextWidth;                {640x??? text}
  105.      $D,$13 : PutMx := MouseTemp shl 1;                    {320x200 graphics}
  106.    else
  107.      PutMx := MouseTemp;                                   {640x??? graphics}
  108.    end;
  109. end;
  110.  
  111. {---------------------------------------------------------------------------}
  112. { converts a standard Y position to a mouse Y position }
  113.  
  114. function PutMy(Y:Integer):Integer;
  115. begin
  116.    if ZeroMouse then
  117.      MouseTemp := Y                            {zero based mouse positioning}
  118.    else
  119.      MouseTemp := pred(Y);                {mouse positioning starts with one}
  120.  
  121.    if MouseTemp < 0 then                                 {clip value to zero}
  122.      MouseTemp := 0;
  123.  
  124.    if TextMouse then
  125.      PutMy := MouseTemp * MouseTextHeight   {convert position for text modes}
  126.    else
  127.      PutMy := MouseTemp;                  {no conversion needed for graphics}
  128. end;
  129.  
  130. {---------------------------------------------------------------------------}
  131. { This procedure is not a standard mouse function. It is however needed to }
  132. { work with the Hercules graphics display. When you use the Hercules }
  133. { graphics display you must call this with the proper display page after }
  134. { you call InitGraph, but before you call InitMouse. InitGraph needs CrtMode}
  135. { to be at 7 to detect the Herc display, but the Mouse needs it at 5 or 6 }
  136. { to detect when the Herc card is in graphs mode. (The Herc card has no }
  137. { provision for telling the system that it is graphics mode.) }
  138. { Note: Be sure to call this procedure with a Pg of -1 if you turn graphics }
  139. { off or anytime before you call InitGraph or DetectGraph. The Mouse unit }
  140. { contains an Exit procedure that calls SetHercMouse with a value of -1 if }
  141. { a Hercules graph mode was selected so that the CrtMode byte will be }
  142. { properly restored on exit from the program. }
  143.  
  144. procedure SetHercMouse(Pg:Integer);
  145. begin
  146.   Case Pg of
  147.     0 : begin
  148.           CrtMode := 6;       { put mouse on Hercules graphics display Pg 0 }
  149.           HercGraphMouse := true;
  150.         end;
  151.     1 : begin
  152.           CrtMode := 5;       { put mouse on Hercules graphics display Pg 1 }
  153.           HercGraphMouse := true;
  154.         end;
  155.   else
  156.     begin
  157.       CrtMode := 7;        { indicate that Hercules display is in text mode }
  158.       HercGraphMouse := false;
  159.     end;
  160.   end;
  161. end;
  162.  
  163. {---------------------------------------------------------------------------}
  164. { Check if a mouse point is currently in the specified area}
  165. { returns true if it is, false if not}
  166. {  Recommended calling method: }
  167. {  If MousePointIn(GetMx(Mx),GetMy(My),x1,y1,x2,y2) then DoSomething;}
  168.  
  169. function MousePointIn(Mx,My, x1,y1,x2,y2:Integer):Boolean;
  170. begin
  171.    if (Mx >= x1) and
  172.       (Mx <= x2) and                               {check if in the box area}
  173.       (My >= y1) and
  174.       (My <= y2) then
  175.      MousePointIn := true                          {<-- return true if it is}
  176.    else
  177.      MousePointIn := false;                   {<-- return false if it is not}
  178. end;
  179.  
  180.  
  181. {---------------------------------------------------------------------------}
  182. function MouseClick:Boolean;           {has the mouse been clicked recently?}
  183. begin
  184.    MouseClick := MouseClicked;               {get a copy of the click status}
  185.    MouseClicked := false;                             {then clear the status}
  186. end;
  187.  
  188.  
  189. {+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++}
  190. { the following are misc subroutines used by the Mouse unit }
  191.  
  192. {---------------------------------------------------------------------------}
  193. { This is called by InitMouse to initialize the mouse mode flags}
  194. { Note: if you are using a Hercules display card in graphics mode,}
  195. { you must call the SetHercMouse() procedure before calling InitMouse}
  196.  
  197. procedure InitMouseMode;
  198. begin
  199.    MouseAreaX1 := 0;                          {initialize mouse bounded area}
  200.    MouseAreaY1 := 0;                               {assume defaults to start}
  201.    MouseAreaX2 := 639;
  202.    MouseAreaY2 := 199;
  203.    MouseTextWidth := 8;                   {BIOS characters are always 8 wide}
  204.    MouseTextHeight := 8;                     {default mouse text height to 8}
  205.  
  206.    if CrtCols = 0 then                        {if BIOS text column width = 0}
  207.      MaxCrtX := 80                              {then force text width to 80}
  208.    else
  209.      MaxCrtX := CrtCols;                       {else use the indicated width}
  210.  
  211.    if CrtRows = 0 then                          {if BIOS text row height = 0}
  212.      MaxCrtY := 25                             {then force text height to 25}
  213.    else
  214.      MaxCrtY := succ(CrtRows);                {else use the indicated height}
  215.  
  216.    if HercGraphMouse then                  {if Herc graphics, handle special}
  217.    begin
  218.      ZeroMouse := true;                 {assume zero mouse for herc graphics}
  219.      TextMouse := false;                            {this is a graphics mode}
  220.      MouseAreaX2 := 719;
  221.      MouseAreaY2 := 347;
  222.      Exit;
  223.    end;
  224.  
  225.    if (CrtMode < 4) or (CrtMode = 7) then          {modes 1-3 and 7 are text}
  226.    begin
  227.      TextMouse := true;                                   {mark as text mode}
  228.      ZeroMouse := false;                  {CRT based text modes start at one}
  229.      MouseAreaX2 := MaxCrtX * MouseTextWidth;    {adjust mouse area based on}
  230.      MouseAreaY2 := MaxCrtY * MouseTextHeight;   {rows and columns BIOS data}
  231.    end
  232.    else                                               {the rest are graphics}
  233.    begin
  234.      ZeroMouse := true;                           {graph modes start at zero}
  235.      TextMouse := false;                                   {mark as graphics}
  236.      case CrtMode of
  237.        $F,$10  : MouseAreaY2 := 349;                       {640x350 graphics}
  238.        $11,$12 : MouseAreaY2 := 479;                       {640x480 graphics}
  239.      end;
  240.    end;
  241. end;
  242.  
  243.  
  244. {---------------------------------------------------------------------------}
  245. {$IFDEF GMouse}                 { if we are using graphics enable this stuff}
  246.  
  247. procedure MakeBGIMouse;     { Create a BGI based mouse cursor on the screen }
  248. var i,ii,Mx1,My1,Mx2,My2:integer;                { called from ShowBGIMouse }
  249.     PixelColor:word;
  250. begin
  251.    {if mouse image is inside BGI safe area, then turn off redraw}
  252.    if (MouseImageX > 0) and (EndImageX < GetMaxX) and
  253.       (MouseImageY > 0) and (EndImageY < GetMaxY) then
  254.      MouseReDraw := false;                {image is safe, so turn off redraw}
  255.  
  256.    with MouseGCursor[MouseGShape] do
  257.    begin
  258.      if MouseSize = 0 then     {no previously allocated, so grab some memory}
  259.      begin
  260.        MouseSize := ImageSize(0,0,15,15);               {compute cursor size}
  261.        GetMem(MouseBack,MouseSize);                    {then grab the memory}
  262.        GetMem(MouseMask,MouseSize);
  263.        GetMem(MouseFore,MouseSize);
  264.      end;
  265.  
  266.      Mx1 := IntLimit(MouseImageX,0,GetMaxX);        {compute real image size}
  267.      My1 := IntLimit(MouseImageY,0,GetMaxY);         {bounded by screen area}
  268.      Mx2 := IntLimit(EndImageX,0,GetMaxX);
  269.      My2 := IntLimit(EndImageY,0,GetMaxY);
  270.      GetImage(Mx1,My1,Mx2,My2,MouseBack^);          {save area behind cursor}
  271.  
  272.      {create the cursor mask with BGI}
  273.      for ii := abs(My1-MouseImageY) to 15-abs(My2-EndImageY) do
  274.      begin
  275.        for i := abs(Mx1-MouseImageX) to 15-abs(Mx2-EndImageX) do
  276.        begin
  277.          if (Def[0][ii] shl i) and $8000 = 0 then
  278.            PixelColor := 0                         {use background for black}
  279.          else
  280.            PixelColor := GetMaxColor;               {use max color for white}
  281.          PutPixel(MouseImageX+i,MouseImageY+ii,PixelColor);
  282.        end;
  283.      end;                                               {save the mask image}
  284.      GetImage(Mx1,My1,Mx2,My2,MouseMask^);
  285.  
  286.      {create the cursor overlay with BGI}
  287.      for ii := abs(My1-MouseImageY) to 15-abs(My2-EndImageY) do
  288.      begin
  289.        for i := abs(Mx1-MouseImageX) to 15-abs(Mx2-EndImageX) do
  290.        begin
  291.          if (Def[1][ii] shl i) and $8000 = 0 then
  292.            PixelColor := 0                         {use background for black}
  293.          else
  294.            PixelColor := MouseColor;         {use specified color foreground}
  295.          PutPixel(MouseImageX+i,MouseImageY+ii,PixelColor);
  296.        end;
  297.      end;                                     {Save the cursor overlay image}
  298.      GetImage(Mx1,My1,Mx2,My2,MouseFore^);
  299.    end;
  300.  
  301.    MouseImageX := Mx1;
  302.    MouseImageY := My1;
  303.    PutImage(MouseImageX,MouseImageY,MouseBack^,NormalPut);   { restore image}
  304.    PutImage(MouseImageX,MouseImageY,MouseMask^,AndPut);       { then display}
  305.    PutImage(MouseImageX,MouseImageY,MouseFore^,OrPut);          { new cursor}
  306. end;
  307.  
  308. {---------------------------------------------------------------------------}
  309. {display a BGI mouse cursor on the screen }
  310.  
  311. procedure ShowBGIMouse;                          { called from IntShowMouse }
  312. begin
  313.   if MouseVisible then       {if mouse currently on, restore old image first}
  314.      PutImage(OldImageX,OldImageY,MouseBack^,NormalPut);
  315.  
  316.   {compute the mouse image position}
  317.   MouseImageX := GetMx(MouseX)-MouseGCursor[MouseGShape].HotX;
  318.   MouseImageY := GetMy(MouseY)-MouseGCursor[MouseGShape].HotY;
  319.   EndImageX := MouseImageX+15;
  320.   EndImageY := MouseImageY+15;
  321.  
  322.   {if cursor never made, or image is partially off screen, remake it}
  323.   if (MouseImageX < 0) or (EndImageX > GetMaxX) or
  324.      (MouseImageY < 0) or (EndImageY > GetMaxY) then
  325.     MouseReDraw := true;
  326.  
  327.   If (MouseSize = 0) or MouseReDraw then
  328.   begin
  329.     MakeBGIMouse;                           { do we need to create a cursor?}
  330.   end
  331.   else
  332.   begin                                   { if cursor already exists, use it}
  333.     GetImage(MouseImageX,MouseImageY,               { save image under mouse}
  334.              EndImageX,EndImageY,MouseBack^);
  335.     PutImage(MouseImageX,MouseImageY,MouseMask^,AndPut);      { then display}
  336.     PutImage(MouseImageX,MouseImageY,MouseFore^,OrPut);         { new cursor}
  337.   end;
  338.   OldImageX := MouseImageX;                          { and save where we are}
  339.   OldImageY := MouseImageY;
  340.   MouseVisible := true;
  341. end;
  342.  
  343. {---------------------------------------------------------------------------}
  344. {hide a BGI mouse cursor on the screen }
  345.  
  346. procedure HideBGIMouse;
  347. begin
  348.    if MouseBack = nil then Exit;    { unless we don't have anything saved}
  349.    PutImage(OldImageX,OldImageY,MouseBack^,NormalPut);
  350. end;
  351.  
  352. {$ENDIF}
  353.  
  354. {---------------------------------------------------------------------------}
  355. {display a simulated mouse cursor on the screen }
  356. procedure ShowMouseSim;
  357. begin
  358. {$IFDEF GMouse}
  359.   if not(TextMouse) then
  360.     ShowBGIMouse;
  361. {$ENDIF}
  362. end;
  363.  
  364. {---------------------------------------------------------------------------}
  365. {hide the simulated mouse cursor on the screen }
  366.  
  367. procedure HideMouseSim;
  368. begin
  369. {$IFDEF GMouse}
  370.   if not(TextMouse) then
  371.     HideBGIMouse;
  372. {$ENDIF}
  373. end;
  374.  
  375.  
  376. {---------------------------------------------------------------------------}
  377. { End Of Include File MOUSESUB.PAS }
  378.